Add PEP 484 type hints to transpiler analysis and utility passes#15832
Add PEP 484 type hints to transpiler analysis and utility passes#15832ShellyGarion merged 36 commits intoQiskit:mainfrom
Conversation
Add `from __future__ import annotations` and PEP 484 type annotations to all 9 analysis passes (CountOps, Depth, Size, Width, NumQubits, NumTensorFactors, CountOpsLongestPath, DAGLongestPath, ResourceEstimation) and 3 utility passes (DAGFixedPoint, FixedPoint, ContainsInstruction). Changes include: - Type-annotate __init__ parameters and run() method signatures with DAGCircuit, bool, str, and -> None return types - Expand sparse docstrings with Args blocks where missing - Fix copy-paste module docstring in contains_instruction.py (was incorrectly 'Check if a property reached a fixed point') - Rename placeholder parameter '_' to 'dag' in ResourceEstimation.run() for clarity
|
Thank you for opening a new pull request. Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient. While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone. One or more of the following people are relevant to this code:
|
|
|
|
This is a pre-written response. I believe this may have been LLM generated without attribution. Please confirm the model used, and that the PR was tested and checked by a human before submission, including validating that the PR truly solves the issue at it was described, and takes into account any comments from maintainers in the base issues. |
|
@jakelishman |
|
Hi @jakelishman ,I've addressed the transparency concern regarding AI assistance, ran all relevant tests locally (12 passed, 0 failed), and believe the changes are correct. Would appreciate your review when you get a chance. Happy to make any adjustments. |
| """Initialize a ``ContainsInstruction`` pass. | ||
|
|
There was a problem hiding this comment.
Our current suggestion is actually to just remove this initial sentence in __init__ if it doesn't provide any additional information
| """Initialize a ``ContainsInstruction`` pass. | |
| """ |
|
|
||
| def __init__(self, instruction_name, recurse: bool = True): | ||
| """ContainsInstruction initializer. | ||
| def __init__(self, instruction_name: str | set[str], recurse: bool = True) -> None: |
There was a problem hiding this comment.
Why change from Iterable to set? That seems more restrictive
There was a problem hiding this comment.
The original docstring already documented this as str | Iterable[str] so I've matched the type hint to that , changed back to str | Iterable[str] using collections.abc.Iterable.
| def run(self, dag): | ||
| """Run the CountOps pass on `dag`.""" | ||
| def run(self, dag: DAGCircuit) -> None: | ||
| """Run the CountOps pass on *dag*.""" |
There was a problem hiding this comment.
*dag* is incorrect here, we use double quotes for code formatting (as you/Claude correctly did in other places):
``dag``
This applies to a bunch of other places too
There was a problem hiding this comment.
Fixed,updated to dag across all affected files.
|
|
||
| """Count the operations in a DAG circuit.""" | ||
|
|
||
| from __future__ import annotations |
There was a problem hiding this comment.
These imports don't seem necessary in every file, could you only add them when required?
There was a problem hiding this comment.
Replaced from __future__ import annotations with a TYPE_CHECKING guard instead ,this way DAGCircuit is only imported during static analysis and has zero runtime cost. Happy to remove it entirely if you'd prefer to keep the diff minimal.
| * Size() | ||
| * CountOps() | ||
| * NumTensorFactors() | ||
| * NumQubits() |
Co-authored-by: Julien Gacon <gaconju@gmail.com>
Hadar01
left a comment
There was a problem hiding this comment.
Thanks for the thorough review @Cryoris ! I've pushed a follow-up commit addressing all feedback:
1.Replaced from future import annotations with TYPE_CHECKING guard in all files
2.Fixed dag → dag across all files
3.Removed redundant init summary lines
4.Changed set[str] → str | Iterable[str] in contains_instruction.py
5.Removed the no-op docstring from resource_estimation.py
Please take another look when you get a chance!
Cryoris
left a comment
There was a problem hiding this comment.
Thanks for the updates, just one thing about line removals and then this LGTM
| # Any modifications or derivative works of this code must retain this | ||
| # copyright notice, and modified files need to carry a notice indicating | ||
| # that they have been altered from the originals. | ||
|
|
There was a problem hiding this comment.
IMO it's much easier to see the module docstring with this whitespace, could you leave these as they were?
There was a problem hiding this comment.
Sorry about that! Restored the blank lines , will keep whitespace as in the originals going forward.
| """Run the FixedPoint pass on ``dag``.""" | ||
| current_value = self.property_set[self._property] | ||
| fixed_point_previous_property = f"_fixed_point_previous_{self._property}" | ||
|
|
There was a problem hiding this comment.
Maybe it'd be best to just revert all these line removals generally 😄
There was a problem hiding this comment.
Sorry about that! Restored the blank lines ,will keep whitespace as in the originals going forward.
Add from __future__ import annotations to all 12 files so that type hints are treated as strings at runtime (fixing Python 3.10 NameError). Keep TYPE_CHECKING guard for DAGCircuit import to satisfy ruff F821. This matches the pattern used in basepasses.py and layout.py. Also fixes contains_instruction.py module docstring (was copy-paste from fixed_point.py).
|
Hey @Cryoris , so I found out why CI was failing , using only the TYPE_CHECKING guard without from future import annotations breaks on Python 3.10 because the type hints get evaluated at runtime and DAGCircuit isn't actually imported. I've added back from future import annotations alongside the guard in all files. Looked at how basepasses.py and layout.py handle it and they use the same combo, so I followed that pattern. Also caught that contains_instruction.py still had the wrong module docstring from fixed_point.py, fixed that too. Let me know if this looks good! |
|
Thanks for the updates, this looks good now. Could you update the PR description with the Claude model used (if you know it)? |
Done @Cryoris |
Coverage Report for CI Build 25011313525Coverage increased (+0.006%) to 87.576%Details
Uncovered ChangesNo uncovered changes found. Coverage Regressions8 previously-covered lines in 2 files lost coverage.
Coverage Stats
💛 - Coveralls |

What this PR does
Adds PEP 484 type annotations and improves docstrings across 12 transpiler
analysis and utility passes:
Analysis passes (
qiskit/transpiler/passes/analysis/):CountOps,Depth,Size,Width,NumQubits,NumTensorFactors,CountOpsLongestPath,DAGLongestPath,ResourceEstimationUtility passes (
qiskit/transpiler/passes/utils/):DAGFixedPoint,FixedPoint,ContainsInstructionSpecific changes
from __future__ import annotationsto all 12 files__init__parameters (bool,str,set[str]) andrun()signatures (dag: DAGCircuit) with-> Nonereturn typesArgsblocks where missingcontains_instruction.py(was a copy-paste leftover: "Check if a property reached a fixed point")
_todaginResourceEstimation.run()for clarity and consistencyMotivation
These passes are part of the public API and used across the transpiler
pipeline, yet they lacked type annotations — hurting IDE auto-completion,
static analysis (mypy / pyright), and Sphinx-generated API documentation.
This is a low-risk, documentation-quality improvement with zero behavioral
changes.
How it was tested
ruff check— all checks passedblack --check— 13 files left unchangedfrom __future__ import annotationsand typed
run()return annotations present in all 12 filesthe full test suite
AI attribution
The preparation of this contribution was assisted by Claude Sonnet 4.6